home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / pcmag / v11n08 / wprints.exe / WPRINC.EXE / DIB.C < prev    next >
C/C++ Source or Header  |  1992-02-13  |  6KB  |  266 lines

  1. #include <windows.h>
  2. #include "wprint.h"
  3. #include "dib.h"
  4.  
  5.  
  6. HANDLE AttemptOpeningDIB (szFile)
  7. LPSTR szFile;
  8. {
  9.     unsigned        fh;
  10.     BITMAPINFOHEADER    bi;
  11.     LPBITMAPINFOHEADER  lpbi;
  12.     DWORD       dwLen = 0;
  13.     DWORD       dwBits;
  14.     HANDLE      hdib;
  15.     HANDLE              h;
  16.     OFSTRUCT        of;
  17.  
  18.     /* Open the file and read the DIB information */
  19.     fh = OpenFile(szFile, &of, OF_READ);
  20.     if (fh == -1)
  21.     return NULL;
  22.  
  23.     hdib = ReadDibBitmapInfo(fh);
  24.     if (!hdib)
  25.     return NULL;
  26.     DibInfo(hdib,&bi);
  27.  
  28.     /* Calculate the memory needed to hold the DIB */
  29.     dwBits = bi.biSizeImage;
  30.     dwLen  = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;
  31.  
  32.     /* Try to increase the size of the bitmap info. buffer to hold the DIB */
  33.     h = GlobalReAlloc(hdib, dwLen, GHND);
  34.     if (!h){
  35.     GlobalFree(hdib);
  36.     hdib = NULL;
  37.     }
  38.     else
  39.     hdib = h;
  40.  
  41.     /* Read in the bits */
  42.     if (hdib){
  43.  
  44.         lpbi = (VOID FAR *)GlobalLock(hdib);
  45.     bigread(fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), dwBits);
  46.     GlobalUnlock(hdib);
  47.     }
  48.     _lclose(fh);
  49.  
  50.     return hdib;
  51. }
  52.  
  53. BOOL DibInfo (hbi, lpbi)
  54. HANDLE hbi;
  55. LPBITMAPINFOHEADER lpbi;
  56. {
  57.     if (hbi){
  58.     *lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
  59.  
  60.     /* fill in the default fields */
  61.     if (lpbi->biSize != sizeof (BITMAPCOREHEADER)){
  62.             if (lpbi->biSizeImage == 0L)
  63.         lpbi->biSizeImage =
  64.             WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
  65.  
  66.             if (lpbi->biClrUsed == 0L)
  67.         lpbi->biClrUsed = DibNumColors (lpbi);
  68.         }
  69.     GlobalUnlock (hbi);
  70.     return TRUE;
  71.     }
  72.     return FALSE;
  73. }
  74.  
  75.  
  76. HANDLE ReadDibBitmapInfo (fh)
  77. int fh;
  78. {
  79.     DWORD     off;
  80.     HANDLE    hbi = NULL;
  81.     int       size;
  82.     int       i;
  83.     WORD      nNumColors;
  84.  
  85.     RGBQUAD FAR       *pRgb;
  86.     BITMAPINFOHEADER   bi;
  87.     BITMAPCOREHEADER   bc;
  88.     LPBITMAPINFOHEADER lpbi;
  89.     BITMAPFILEHEADER   bf;
  90.     DWORD          dwWidth = 0;
  91.     DWORD          dwHeight = 0;
  92.     WORD           wPlanes, wBitCount;
  93.  
  94.     if (fh == -1)
  95.         return NULL;
  96.  
  97.     /* Reset file pointer and read file header */
  98.     off = _llseek(fh, 0L, SEEK_CUR);
  99.     if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
  100.         return FALSE;
  101.  
  102.     /* Do we have a RC HEADER? */
  103.     if (!ISDIB (bf.bfType)) {
  104.         bf.bfOffBits = 0L;
  105.     _llseek (fh, off, SEEK_SET);
  106.     }
  107.     if (sizeof (bi) != _lread (fh, (LPSTR)&bi, sizeof(bi)))
  108.         return FALSE;
  109.  
  110.     nNumColors = DibNumColors (&bi);
  111.  
  112.     /* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
  113.      * and extract the field information accordingly. If a BITMAPCOREHEADER,
  114.      * transfer it's field information to a BITMAPINFOHEADER-style block
  115.      */
  116.     switch (size = (int)bi.biSize){
  117.     case sizeof (BITMAPINFOHEADER):
  118.             break;
  119.  
  120.     case sizeof (BITMAPCOREHEADER):
  121.  
  122.         bc = *(BITMAPCOREHEADER*)&bi;
  123.  
  124.         dwWidth   = (DWORD)bc.bcWidth;
  125.         dwHeight  = (DWORD)bc.bcHeight;
  126.         wPlanes   = bc.bcPlanes;
  127.         wBitCount = bc.bcBitCount;
  128.  
  129.             bi.biSize               = sizeof(BITMAPINFOHEADER);
  130.         bi.biWidth          = dwWidth;
  131.         bi.biHeight         = dwHeight;
  132.         bi.biPlanes         = wPlanes;
  133.         bi.biBitCount       = wBitCount;
  134.  
  135.             bi.biCompression        = BI_RGB;
  136.             bi.biSizeImage          = 0;
  137.             bi.biXPelsPerMeter      = 0;
  138.             bi.biYPelsPerMeter      = 0;
  139.             bi.biClrUsed            = nNumColors;
  140.             bi.biClrImportant       = nNumColors;
  141.  
  142.         _llseek (fh, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER), SEEK_CUR);
  143.             break;
  144.  
  145.     default:
  146.         /* Not a DIB! */
  147.         return NULL;
  148.     }
  149.  
  150.     /*  Fill in some default values if they are zero */
  151.     if (bi.biSizeImage == 0){
  152.     bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount)
  153.              * bi.biHeight;
  154.     }
  155.     if (bi.biClrUsed == 0)
  156.     bi.biClrUsed = DibNumColors(&bi);
  157.  
  158.     /* Allocate for the BITMAPINFO structure and the color table. */
  159.     hbi = GlobalAlloc (GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
  160.     if (!hbi)
  161.         return NULL;
  162.     lpbi = (VOID FAR *)GlobalLock (hbi);
  163.     *lpbi = bi;
  164.  
  165.     /* Get a pointer to the color table */
  166.     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
  167.     if (nNumColors){
  168.     if (size == sizeof(BITMAPCOREHEADER)){
  169.         /* Convert a old color table (3 byte RGBTRIPLEs) to a new
  170.          * color table (4 byte RGBQUADs)
  171.              */
  172.         _lread (fh, (LPSTR)pRgb, nNumColors * sizeof(RGBTRIPLE));
  173.  
  174.         for (i = nNumColors - 1; i >= 0; i--){
  175.                 RGBQUAD rgb;
  176.  
  177.                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
  178.                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
  179.                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
  180.                 rgb.rgbReserved = (BYTE)0;
  181.  
  182.                 pRgb[i] = rgb;
  183.             }
  184.         }
  185.     else
  186.             _lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBQUAD));
  187.     }
  188.  
  189.     if (bf.bfOffBits != 0L)
  190.         _llseek(fh,off + bf.bfOffBits,SEEK_SET);
  191.  
  192.     GlobalUnlock(hbi);
  193.     return hbi;
  194. }
  195.  
  196. WORD PaletteSize (pv)
  197. VOID FAR * pv;
  198. {
  199.     LPBITMAPINFOHEADER lpbi;
  200.     WORD           NumColors;
  201.  
  202.     lpbi      = (LPBITMAPINFOHEADER)pv;
  203.     NumColors = DibNumColors(lpbi);
  204.  
  205.     if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
  206.         return NumColors * sizeof(RGBTRIPLE);
  207.     else
  208.         return NumColors * sizeof(RGBQUAD);
  209. }
  210.  
  211. WORD DibNumColors (pv)
  212. VOID FAR * pv;
  213. {
  214.     int         bits;
  215.     LPBITMAPINFOHEADER  lpbi;
  216.     LPBITMAPCOREHEADER  lpbc;
  217.  
  218.     lpbi = ((LPBITMAPINFOHEADER)pv);
  219.     lpbc = ((LPBITMAPCOREHEADER)pv);
  220.  
  221.     /*  With the BITMAPINFO format headers, the size of the palette
  222.      *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
  223.      *  is dependent on the bits per pixel ( = 2 raised to the power of
  224.      *  bits/pixel).
  225.      */
  226.     if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){
  227.         if (lpbi->biClrUsed != 0)
  228.             return (WORD)lpbi->biClrUsed;
  229.         bits = lpbi->biBitCount;
  230.     }
  231.     else
  232.         bits = lpbc->bcBitCount;
  233.  
  234.     switch (bits){
  235.     case 1:
  236.         return 2;
  237.     case 4:
  238.         return 16;
  239.     case 8:
  240.         return 256;
  241.     default:
  242.         /* A 24 bitcount DIB has no color table */
  243.         return 0;
  244.     }
  245. }
  246.  
  247.  
  248. DWORD PASCAL bigread (fh, pv, ul)
  249. int       fh;
  250. VOID far      *pv;
  251. DWORD         ul;
  252. {
  253.     DWORD     ulT = ul;
  254.     BYTE huge *hp = pv;
  255.  
  256.     while (ul > (DWORD)MAXREAD) {
  257.     if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
  258.         return 0;
  259.     ul -= MAXREAD;
  260.     hp += MAXREAD;
  261.     }
  262.     if (_lread(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
  263.     return 0;
  264.     return ulT;
  265. }
  266.